package com.huiminpay.transaction.controller;

import com.alibaba.fastjson.JSON;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.huiminpay.common.cache.domain.BusinessException;
import com.huiminpay.common.cache.domain.CommonErrorCode;
import com.huiminpay.common.cache.util.AmountUtil;
import com.huiminpay.common.cache.util.BrowserType;
import com.huiminpay.common.cache.util.EncryptUtil;
import com.huiminpay.common.cache.util.ParseURLPairUtil;
import com.huiminpay.paymentagent.api.conf.AliConfigParam;
import com.huiminpay.paymentagent.api.dto.PaymentResponseDTO;
import com.huiminpay.paymentagent.api.service.IPayAgentService;
import com.huiminpay.transaction.api.dto.OrderResultDTO;
import com.huiminpay.transaction.api.dto.PayChannelParamDTO;
import com.huiminpay.transaction.api.dto.PayOrderDTO;
import com.huiminpay.transaction.service.IPayChannelService;
import com.huiminpay.transaction.service.ITransactionService;
import com.huiminpay.transaction.vo.OrderConfirmVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

@Controller
@Slf4j
public class PayController {
    @Reference
    ITransactionService transactionService;
    @Reference
    IPayChannelService payChannelService;
    @Reference
    IPayAgentService payAgentService;
    /**
     * 支付入口
     * @param ticket
     * @param request
     * @return
     */
    @RequestMapping(value = "/qr/{ticket}")
    public String payEntry(@PathVariable("ticket") String ticket, HttpServletRequest request) throws Exception {
        if(StringUtils.isBlank(ticket)){
            throw new BusinessException(CommonErrorCode.CUSTOM);
        }
        String jsonStr = EncryptUtil.decodeUTF8StringBase64(ticket);
        PayOrderDTO payOrderDTO = JSON.parseObject(jsonStr, PayOrderDTO.class);

        String params = ParseURLPairUtil.parseURLPair(payOrderDTO);

        String header = request.getHeader("User-Agent");
        BrowserType browserType = BrowserType.valueOfUserAgent(header);
        if(browserType.equals(BrowserType.ALIPAY)){
            // 代表支付宝客户端
            return "forward:/pay-page?"+params;
        }else if (browserType.equals(BrowserType.MOBILE_BROWSER)){
            return "forward:/pay-page?"+params;
        }

        return "pay_error";
    }


    /**
     * 支付入口页面
     * @return
     */
    @RequestMapping(value = "/pay-page")
    public String payPage() {
        return "pay";
    }
    @RequestMapping(value = "/success")
    public String success(String out_trade_no, Model model) {
        System.out.println(out_trade_no+"=========");
        OrderResultDTO orderResultDTO = transactionService.selectPayOrderByOrderNo(out_trade_no);
        String msg = "支付失败";
        // 根据订单号查询订单信息，根据状态 判断支付情况
        if(orderResultDTO.getTradeState().equals("2")){
            msg = "支付成功";
        }else{
            PayChannelParamDTO payChannelParamDTO = payChannelService.queryParamByAppPlatformAndPayChannel(orderResultDTO.getAppId(), orderResultDTO.getChannel(), orderResultDTO.getPayChannel());
            String param = payChannelParamDTO.getParam();
            AliConfigParam aliConfigParam = JSON.parseObject(param, AliConfigParam.class);
            //查询支付宝api
            PaymentResponseDTO paymentResponseDTO = payAgentService.queryAlipayOrderInfo(aliConfigParam, out_trade_no);
            log.info("[]",paymentResponseDTO);
            if(paymentResponseDTO.getContent().equals("TRADE_SUCCESS")){
                msg = "支付成功";
                orderResultDTO.setTradeState("2");
                orderResultDTO.setPaySuccessTime(LocalDateTime.now());
                transactionService.updatePayorder(orderResultDTO);
            }
        }
        model.addAttribute("msg",msg);
        return "pay_success";
    }
    /**
     * 支付宝下单入口
     * @param orderConfirmVO
     */
    @PostMapping("createAliPayOrder")
    public void createAlipayWapOrder(OrderConfirmVO orderConfirmVO, HttpServletResponse response) throws IOException {

        PayOrderDTO payOrderDTO = new PayOrderDTO();
        BeanUtils.copyProperties(orderConfirmVO,payOrderDTO);
        // 门店ID属性问题
        payOrderDTO.setStoreId(Long.valueOf(orderConfirmVO.getStoreId()));
        // 订单金额单位问题
        payOrderDTO.setTotalAmount(Integer.valueOf(AmountUtil.changeY2F(orderConfirmVO.getTotalAmount())));
        String html = transactionService.createAlipayWapOrder(payOrderDTO);

        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write(html);
        response.getWriter().close();
        response.getWriter().flush();
    }

    @RequestMapping(value = "/alipayNotify")
    public void alipayNotify(HttpServletResponse response,HttpServletRequest request) throws IOException {
        // 更新订单状态？  01.参数（订单号，状态，其他信息） 02.安全问题
        Map<String, String[]> parameterMap = request.getParameterMap();
        log.info("{}",parameterMap);
        Map<String,String> map = new HashMap<>();

        Set<String> strings = parameterMap.keySet();
        for (String key:strings) {
            map.put(key,parameterMap.get(key)[0]);
        }

        // 根据订单号查询订单信息为了获取查询渠道参数的条件
        String out_trade_no = map.get("out_trade_no");
        OrderResultDTO orderResultDTO = transactionService.selectPayOrderByOrderNo(out_trade_no);
        PayChannelParamDTO payChannelParamDTO = payChannelService.queryParamByAppPlatformAndPayChannel(orderResultDTO.getAppId(), orderResultDTO.getChannel(), orderResultDTO.getPayChannel());
        String param = payChannelParamDTO.getParam();
        AliConfigParam aliConfigParam = JSON.parseObject(param, AliConfigParam.class);


        // 1.验证签名
        String publicKey = aliConfigParam.getAlipayPublicKey();
        String charset = aliConfigParam.getCharest();
        String signType = aliConfigParam.getSigntype();
        try {
            boolean b = AlipaySignature.rsaCheckV1(map, publicKey, charset, signType);
            if(b){
                // 2. 更新状态 支付宝状态和惠民系统状态转换
                String trade_status = map.get("trade_status");
                //交易状态支付状态,0-订单生成,1-支付中(目前未使用),2-支付成功,3-业务处理完成 4.交易已关闭
                String tradeState = orderResultDTO.getTradeState();
                if(trade_status.equals("TRADE_SUCCESS")){
                    tradeState = "2";
                    orderResultDTO.setPaySuccessTime(LocalDateTime.now());
                    String payChannelTradeNo = map.get("trade_no");
                    orderResultDTO.setPayChannelTradeNo(payChannelTradeNo);
                }else if(trade_status.equals("TRADE_FINISHED")){
                    tradeState = "3";
                }else if(trade_status.equals("TRADE_CLOSED")){
                    tradeState = "4";
                }
                orderResultDTO.setTradeState(tradeState);

                transactionService.updatePayorder(orderResultDTO);
                response.getWriter().write("success");

            }else {
                response.getWriter().write("验证签名失败");
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            response.getWriter().write("fail");
        }

        response.getWriter().flush();
        response.getWriter().close();
    }
}
